package com.wmx.collection.hashmap;

import com.wmx.collection.Student;
import org.springframework.beans.BeanUtils;
import sun.reflect.generics.tree.Tree;

import java.util.HashMap;
import java.util.Hashtable;
import java.util.LinkedHashMap;
import java.util.TreeMap;

/****************************************************************
 * Java面试题之有没有有顺序的Map实现类，如果有，他们是怎么实现有序的？
 * HashMap和HashTable 都不是有序的。
 * TreeMap和LinkedHashMap都是有序的。（TreeMap默认是key升序，LinkedHashmap默认是数据插入顺序）
 * LinkedHashMap是按照插入顺序排序，而TreeMap是按照Key的自然顺序或者Comparator的顺序进行排序。
 * 在实现原理上LinkedHashMap是双向链表，TreeMap是红黑树。TreeMap还有个好兄弟叫TreeSet，实现原理是一样的。
 * TreeMap是基于比较器Comparator来实现有序的。
 * LinkedHashMap是基于链表来实现数据插入有序的。
 *
 *
 * TreeMap : 怎样保证有序性的。
 * treeMap 是按照key的自然顺序或者Comparator的顺序进行排序的。
 *
 *
 * 在看treeMap源码的时候看见有个关键字 transient
 * 在讨论transient之前，有必要先搞清楚Java中序列化的含义：
 * Java中对象的序列化指的是将对象转换成以字节序列的形式来表示，
 * 这些字节序列包含了对象的数据和信息，一个序列化后的对象可以被写到数据库或文件中，
 * 也可用于网络传输，一般当我们使用缓存cache（内存空间不够有可能会本地存储到硬盘）
 * 或远程调用rpc（网络传输）的时候，经常需要让我们的实体类实现Serializable接口，目的就是为了让其可序列化。
 * Java中transient关键字的作用，简单地说，就是让某些被修饰的成员属性变量不被序列化
 * 1、类中的字段值可以根据其它字段推导出来，如一个长方形类有三个属性：长度、宽度、面积（示例而已，一般不会这样设计），那么在序列化的时候，面积这个属性就没必要被序列化了；
 * 2、其它，看具体业务需求吧，哪些字段不想被序列化；
 *    记得之前看HashMap源码的时候，发现有个字段是用transient修饰的，我觉得还是有道理的，确实没必要对这个modCount字段进行序列化，因为没有意义，modCount主要用于判断HashMap是否被修改（像put、remove操作的时候，modCount都会自增），对于这种变量，一开始可以为任何值，0当然也是可以（new出来、反序列化出来、或者克隆clone出来的时候都是为0的），没必要持久化其值。
 *
 *
 *
*******************************************************************/
public class HashMapTest {

    public static void main(String[] args) {

        Student student = new Student("wumengxin",10);
        System.out.println(student.hashCode());
        student.setName("wumengxin");
        student.setAge(10);
        System.out.println(student.hashCode());
        HashMap<String,String> hashMap = new HashMap<>();

        //***************TreeMap是怎样保证有序性的**********************
        TreeMap treeMap = new TreeMap();
        treeMap.put("wumengixn","1");
        treeMap.put("wumengixn1","2");
        treeMap.put("wumengixn2","3");
        treeMap.put("wumengixn3","4");

        System.out.println(treeMap);
        System.out.println("treeMap中的第一个数据："+treeMap.firstKey());
        System.out.println("treeMap中的最后一个数据："+treeMap.lastKey());
        //*****************TreeMap按照key的自然顺序排序和comparator顺序进行排序********************************
        TreeMap<String, String> map = new TreeMap<String, String>();
        map.put("f", "12345");
        map.put("b", "12345");
        map.put("e", "12345");
        map.put("d", "12345");
        map.put("g", "644");
        map.put("c", "980000000");
        map.put("a", "12345");
        System.out.println("TreeMap按照key的自然顺序排序"+map);
        System.out.println("TreeMap中的第一个数据"+map.firstKey());

        //******************LinkedHashMap有序性研究*********************************
        LinkedHashMap<String,String> linkedHashMap = new LinkedHashMap();
        linkedHashMap.put("g","1");
        linkedHashMap.put("b","1");
        linkedHashMap.put("a","1");
        linkedHashMap.put("c","1");
        linkedHashMap.put("e","1");

        System.out.println("LinkedHashMap有序性研究"+linkedHashMap); //按照插入顺序进行排列的

    }
}
